﻿using JGSY.SerialCommunication.UpperComputer.Core;
using JGSY.SerialCommunication.UpperComputer.Core.EnumType;
using JGSY.SerialCommunication.UpperComputer.IComponent;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace JGSY.SerialCommunication.UpperComputer.Modbus
{
    /// <summary>
    /// Modbus通信的基础类，提供Modbus协议通信所需的基本功能和工具方法
    /// </summary>
    public abstract class ModbusBase : IDisposable
    {

        #region 配置  属性 对象 


        /// <summary>
        /// 事务标识符字段TCP/UDP 
        /// Transaction ID（事务标识符）2 字节，大端序（Big-Endian）。由客户端生成，用于匹配请求和响应（类似序列号）。服务器在响应中原样返回该值。可以递增或随机生成，但必须唯一。
        /// TCP ADU由Modbus应用协议(MBAP)报文头和Modbus PDU组成。 MBAP是一个通用的报文头，依赖于可靠的网络层。
        ///[ MBAP Header (7 bytes) ] + [ Modbus PDU (N bytes) ]
        ///[Transaction ID（事务标识符）2字节]+[Protocol ID（协议标识符）2 字节]+[Length（长度字段）2 字节]+[Unit ID（单元标识符）1 字节]+[ Modbus PDU (N bytes) ]
        /// </summary>
        public static int TransactionId = 0;

        /// <summary>
        /// 字节序设置，控制多字节数据在通信中的字节排列顺序
        /// </summary>
        public virtual EndianType EndianType { get; set; } = EndianType.AB;

        /// <summary>
        /// 通信单元接口，负责实际的物理层通信实现
        /// </summary>
        public ICommunicationUnit? CommunicationUnit { get; set; } = null;

        /// <summary>
        /// TCP/UDP通讯，即isModbusTcp=true，
        /// 作用：获取功能码允许的最大数量
        /// 读线圈、读离散输入、写多个线圈 RTU/ASCII：2000，TCP/UDP：65535
        /// 读保持寄存器、读输入寄存器、写多个保持寄存器 RTU/ASCII：125，TCP/UDP：65535
        /// 写单个线圈、写单个保持寄存器 RTU/ASCII：1，TCP/UDP：1
        /// </summary>
        public virtual bool IsModbusTcp { get; set; } = false;
        /// <summary>
        /// 是否忽略MABP，默认忽略，即false。
        /// </summary>
        public virtual bool IsIgnoreMABP { get; set; } = false;
        
        #endregion


        #region 基类 Build PDU  

        ///功能码 1、2、3、4（读保持寄存器相关）
        ///在 Modbus 协议中，当使用读保持寄存器（功能码 1、2、3、4 等，这里以 3 为例）功能时，PDU（协议数据单元）的格式就是从站地址、功能码、起始地址（2 字节，高字节在前、低字节在后）、寄存器数量（2 字节，高字节在前、低字节在后） 。如给定示例中，起始地址 10（十六进制 0x000A），以大端字节序表示就是 0 和 10 两个字节，寄存器数量 5（十六进制 0x0005）同样以大端字节序表示为 0 和 5 两个字节，所以[从站地址, 3, 0, 10, 0, 5] 的格式描述是正确的。
        ///功能码 5、6（写单个寄存器）
        ///写单个寄存器功能的 PDU 格式是从站地址、功能码、寄存器地址（2 字节，高字节在前、低字节在后）、寄存器值（2 字节，高字节在前、低字节在后）。对于示例里寄存器地址 20（十六进制 0x0014），大端字节序表示为 0 和 20 两个字节，寄存器值 150（十六进制 0x0096）大端字节序表示为 0 和 150 两个字节，因此[从站地址, 6, 0, 20, 0, 150] 的格式符合 Modbus 协议规定。
        ///功能码 15、16（写多个寄存器）
        ///写多个寄存器功能的 PDU 格式为从站地址、功能码、起始地址（2 字节，高字节在前、低字节在后）、寄存器数量（2 字节，高字节在前、低字节在后）、字节数（表示后续寄存器值的总字节数）、寄存器值（每个寄存器值占 2 字节，按顺序依次排列，高字节在前、低字节在后） 。在给定例子中，起始地址 30（十六进制 0x001E）大端字节序为 0 和 30 两个字节，寄存器数量 3（十六进制 0x0003）大端字节序为 0 和 3 两个字节，3 个寄存器值每个 2 字节共 6 字节，其值分别按大端字节序排列，所以[从站地址, 16, 0, 30, 0, 3, 6, 0, 100, 0, 200, 1, 2C] 是正确的格式表述。
        ///若功能码为 1 2 3 4（读保持寄存器），后续为[从站地址,功能码,起始地址高字节,起始地址低字节,寄存器数量高字节,寄存器数量低字节]。比如起始地址为 10（十六进制 0x000A），寄存器数量为 5（十六进制 0x0005），则为[从站地址, 3, 0, 10, 0, 5]。
        ///若功能码为 5 6（写单个寄存器），后续为[从站地址, 功能码, 寄存器地址高字节, 寄存器地址低字节, 寄存器值高字节, 寄存器值低字节]。例如寄存器地址为 20（十六进制 0x0014），寄存器值为 150（十六进制 0x0096），则为[从站地址, 6, 0, 20, 0, 150]。
        ///若功能码为 15 16（写多个寄存器），后续为[从站地址, 功能码, 起始地址高字节, 起始地址低字节, 寄存器数量高字节, 寄存器数量低字节, 字节数, 寄存器值1高字节, 寄存器值1低字节, ...]。假设起始地址 30（十六进制 0x001E），寄存器数量 3（十六进制 0x0003），三个寄存器值分别为 100（十六进制 0x0064）、200（十六进制 0x00C8）、300（十六进制 0x012C），则为[从站地址, 16, 0, 30, 0, 3, 6, 0, 100, 0, 200, 1, 2C] 。这里 “字节数” 是指后续寄存器值所占字节总数，此例中有 3 个寄存器值，每个 2 字节，共 6 字节。
        /// <summary>
        /// 创建Modbus RTU/TCP协议数据单元(PDU)
        /// 支持功能码包括: 读线圈(0x01)、读寄存器(0x03)、写单个线圈(0x05)、写单个寄存器(0x06)、写多个线圈(0x0F)、写多个寄存器(0x10)等
        /// </summary>
        /// <param name="slaveNum">从站地址(1-247)</param>
        /// <param name="funcCode">功能码</param>
        /// <param name="startAddr">起始地址</param>
        /// <param name="quantityOrValueOrLength">寄存器/线圈数量(读操作)/值(写单个寄存器/线圈)</param>
        /// <param name="values">写多个寄存器/线圈时的值字节数组</param>
        /// <returns>包含PDU数据的字节列表</returns>
        /// <exception cref="ArgumentOutOfRangeException">参数超出Modbus协议允许范围</exception>
        /// <exception cref="ArgumentException">不支持的功能码或参数组合</exception>
        public virtual List<byte> BuildProtocolDataUnit(byte slaveNum, byte funcCode, ushort startAddr, ushort quantityOrValueOrLength = 0, byte[] values = null)
        {
            // 验证从站地址有效性
            if (slaveNum < 1 || slaveNum > 247)
                throw new ArgumentOutOfRangeException(nameof(slaveNum), "从站地址必须在1-247之间");

            // 判断操作类型
            bool isReadOperation = IsReadFunctionCode(funcCode);
            bool isWriteSingle = IsWriteSingleFunctionCode(funcCode);
            bool isWriteMultiple = IsWriteMultipleFunctionCode(funcCode);

            // 验证功能码有效性
            if (!isReadOperation && !isWriteSingle && !isWriteMultiple)
                throw new ArgumentException($"不支持的功能码: 0x{funcCode:X2}", nameof(funcCode));

            // 创建PDU基础数据 从站地址 + 功能码
            List<byte> commonPduParams = new List<byte> { slaveNum, funcCode };

            // 添加起始地址 (Modbus协议使用大端字节序)
            commonPduParams.AddRange(ToBigEndianBytes(startAddr));

            if (isReadOperation)
            {
                // 读操作: 添加寄存器/线圈数量
                // 不同功能码支持的最大数量不同(如0x03功能码最大支持125个寄存器)
                if (quantityOrValueOrLength < 1 || quantityOrValueOrLength > GetMaxQuantity(funcCode))
                    throw new ArgumentOutOfRangeException(nameof(quantityOrValueOrLength),
                        $"读数量必须在1-{GetMaxQuantity(funcCode)}之间");

                commonPduParams.AddRange(ToBigEndianBytes(quantityOrValueOrLength));
            }
            else if (isWriteSingle)
            {
                // 写单个寄存器/线圈: 添加值(对于写单个操作,quantityOrValueOrLength)
                commonPduParams.AddRange(ToBigEndianBytes(quantityOrValueOrLength));
            }
            else if (isWriteMultiple)
            {
                // 写多个寄存器/线圈
                if (quantityOrValueOrLength < 1 || quantityOrValueOrLength > GetMaxQuantity(funcCode))
                    throw new ArgumentOutOfRangeException(nameof(quantityOrValueOrLength),
                        $"写数量必须在1-{GetMaxQuantity(funcCode)}之间");

                // 计算字节数(线圈按位存储,每8个线圈占1字节;寄存器每个占2字节) int byteCount = (int)Math.Ceiling(quantityOrValueOrLength / 8.0);==(quantityOrValueOrLength + 7) / 8
                int byteCount = funcCode == 0x0F ? (quantityOrValueOrLength + 7) / 8 : quantityOrValueOrLength * 2;

                // 添加数量
                commonPduParams.AddRange(ToBigEndianBytes(quantityOrValueOrLength));
                // 添加字节数
                commonPduParams.Add((byte)byteCount);

                // 添加值字节数组
                if (values == null || values.Length != byteCount)
                    throw new ArgumentException($"值字节数组长度必须为{byteCount}", nameof(values));
                if (funcCode == 0x0F) // 写多个线圈 (处理位编码)
                {
                    // 验证并转换线圈状态（确保按位编码且大端序）
                    //byte[] coilBytes = EnsureBigEndianRegisters(values);// EncodeCoilBits(values, quantityOrValueOrLength);
                    commonPduParams.AddRange(values);
                }
                else // 写多个寄存器 (处理大端序)
                {
                    // 确保每个寄存器值（2字节）是大端序
                    commonPduParams.AddRange(values); 
                }
            }

            return commonPduParams;
        }
        /// <summary>
        /// 判断是否为读功能码
        /// </summary>
        /// <param name="funcCode"></param>
        /// <returns></returns> 
        private bool IsReadFunctionCode(byte funcCode) => funcCode == 0x01 || funcCode == 0x02 || funcCode == 0x03 || funcCode == 0x04;
        /// <summary>
        /// 判断是否为写单个功能码
        /// </summary>
        /// <param name="funcCode"></param>
        /// <returns></returns> 
        private bool IsWriteSingleFunctionCode(byte funcCode) => funcCode == 0x05 || funcCode == 0x06;
        /// <summary>
        /// 判断是否为写多个功能码
        /// </summary>
        /// <param name="funcCode"></param>
        /// <returns></returns> 
        private bool IsWriteMultipleFunctionCode(byte funcCode) => funcCode == 0x0F || funcCode == 0x10;

        /// <summary>
        /// 获取功能码允许的最大数量
        /// </summary>
        /// <param name="funcCode">功能码</param>
        /// <param name="isModbusTcp">是否是Tcp或者UDP</param>
        /// <returns>允许的最大数量</returns>
        /// <exception cref="ArgumentException"></exception>
        private int GetMaxQuantity(byte funcCode, bool isModbusTcp = false)
        {
            switch (funcCode)
            {
                // 读线圈
                case 0x01:
                    return isModbusTcp ? 2000 : 2000;

                // 读离散输入
                case 0x02:
                    return isModbusTcp ? 2000 : 2000;

                // 读保持寄存器
                case 0x03:
                    return isModbusTcp ? 125 : 125;

                // 读输入寄存器
                case 0x04:
                    return isModbusTcp ? 125 : 125;

                // 写单个线圈
                case 0x05:
                    return 1;

                // 写单个保持寄存器
                case 0x06:
                    return 1;

                // 写多个线圈
                case 0x0F:
                    return isModbusTcp ? 1968 : 1968;

                // 写多个保持寄存器
                case 0x10:
                    return isModbusTcp ? 123 : 123;

                default:
                    throw new ArgumentException($"不支持的功能码: 0x{funcCode:X2}", nameof(funcCode));
            }
        }
        private byte[] ToBigEndianBytes(ushort value) => BitConverter.IsLittleEndian ? BitConverter.GetBytes(value).Reverse().ToArray() : BitConverter.GetBytes(value);


        // 确保寄存器值是大端序（高字节在前）
        private byte[] EnsureBigEndianRegisters(byte[] registerValues)
        {
            // 如果是小端序系统，需要调整每个寄存器（2字节）的字节序
            if (BitConverter.IsLittleEndian)
            {
                byte[] result = new byte[registerValues.Length];

                for (int i = 0; i < registerValues.Length; i += 2)
                {
                    if (i + 1 < registerValues.Length)
                    {
                        // 交换字节顺序（小端转大端）
                        result[i] = registerValues[i + 1];
                        result[i + 1] = registerValues[i];
                    }
                    else
                    {
                        // 单字节（理论上不会出现，因为寄存器是2字节）
                        result[i] = registerValues[i];
                    }
                }

                return result;
            }

            // 大端序系统直接返回
            return registerValues;
        }

        #endregion


        #region 读 写

        // 1. 读取线圈（线圈状态 、输入线圈）使用1、2功能码
        /// <summary>
        /// 读取线圈状态或输入线圈
        /// </summary>
        /// <param name="slaveNum">从站地址</param>
        /// <param name="funcCode">功能码(0x01-读线圈,0x02-读输入线圈)</param>
        /// <param name="startAddr">起始地址</param>
        /// <param name="count">读取数量</param>
        /// <returns>包含布尔数组的结果对象</returns>
        public virtual Result<bool> ReadCoils(byte slaveNum, byte funcCode, ushort startAddr, ushort count)
        {
            try
            {
                // 验证功能码是否为01或02
                if (funcCode != 0x01 && funcCode != 0x02)
                {
                    return Result<bool>.Failed($"无效的功能码: {funcCode}，预期01或02");
                }

                // 构建请求PDU
                var pdu = BuildProtocolDataUnit(slaveNum, funcCode, startAddr, count);

                // 发送请求并接收响应
                var response = SendRequest(pdu);

                // 验证响应
                if (response.Length < 3 || response[0] != slaveNum || response[1] != funcCode)
                {
                    return Result<bool>.Failed("无效的响应格式");
                }

                // 检查是否为异常响应
                if ((response[1] & 0x80) == 0x80)
                {
                    return Result<bool>.Failed($"Modbus异常: 错误码 {response[2]}");
                }

                byte byteCount = response[2];
                byte[] coilData = new byte[byteCount];
                Array.Copy(response, 3, coilData, 0, byteCount);

                // 验证字节数是否符合预期
                int expectedByteCount = (count + 7) / 8;
                if (byteCount != expectedByteCount)
                {
                    return Result<bool>.Failed($"响应字节数不匹配，预期: {expectedByteCount}，实际: {byteCount}");
                }

                // 解析线圈状态
                bool[] coils = new bool[count];
                for (int i = 0; i < count; i++)
                {
                    int byteIndex = i / 8;
                    int bitIndex = i % 8;

                    if (byteIndex < byteCount)
                    {
                        // 功能码01(读线圈)和02(读离散输入)的位解析逻辑相同
                        coils[i] = (coilData[byteIndex] & (1 << bitIndex)) != 0;
                    }
                }

                return Result<bool>.Success(coils.ToList());
            }
            catch (Exception ex)
            {
                return Result<bool>.Failed($"读取线圈失败: {ex.Message}");
            }
        } 

        // 2. 读取寄存器（保持型寄存器、输入寄存器）使用3、4功能码
        /// <summary>
        /// 读取保持型寄存器或输入寄存器
        /// </summary>
        /// <typeparam name="T">返回数据类型</typeparam>
        /// <param name="slaveNum">从站地址</param>
        /// <param name="funcCode">功能码(0x03-读保持寄存器,0x04-读输入寄存器)</param>
        /// <param name="startAddr">起始地址</param>
        /// <param name="dataCount">读取数量</param>
        /// <returns>包含指定类型数组的结果对象</returns>
        public virtual Result<T> ReadRegisters<T>(byte slaveNum, byte funcCode, ushort startAddr, ushort dataCount)
        {
            try
            {
                // 构建请求PDU
                var pdu = BuildProtocolDataUnit(slaveNum, funcCode, startAddr, dataCount);

                // 发送请求并接收响应
                var response = SendRequest(pdu);

                // 验证响应
                if (response.Length < 3 || response[0] != slaveNum || response[1] != funcCode)
                {
                    return Result<T>.Failed("无效的响应格式");
                }

                // 检查是否为异常响应
                if ((response[1] & 0x80) == 0x80)
                {
                    return Result<T>.Failed($"Modbus异常: 错误码 {response[2]}");
                }

                byte byteCount = response[2];
                byte[] registerData = new byte[byteCount];
                Array.Copy(response, 3, registerData, 0, byteCount);

                // 解析寄存器值
                T[] registers = new T[dataCount];
                for (int i = 0; i < dataCount; i++)
                {
                    int byteIndex = i * 2;
                    if (byteIndex + 1 < byteCount)
                    {
                        ushort value = (ushort)((registerData[byteIndex] << 8) | registerData[byteIndex + 1]);

                        // 根据目标类型转换
                        if (typeof(T) == typeof(ushort))
                        {
                            registers[i] = (T)(object)value;
                        }
                        else if (typeof(T) == typeof(short))
                        {
                            registers[i] = (T)(object)(short)value;
                        }
                        else if (typeof(T) == typeof(int))
                        {
                            // 假设两个寄存器组成一个int
                            if (i + 1 < dataCount && byteIndex + 3 < byteCount)
                            {
                                int intValue = (registerData[byteIndex] << 24) |
                                              (registerData[byteIndex + 1] << 16) |
                                              (registerData[byteIndex + 2] << 8) |
                                               registerData[byteIndex + 3];
                                registers[i] = (T)(object)intValue;
                                i++; // 跳过下一个寄存器
                            }
                        }
                        else if (typeof(T) == typeof(float))
                        {
                            // 假设两个寄存器组成一个float
                            if (i + 1 < dataCount && byteIndex + 3 < byteCount)
                            {
                                int intValue = (registerData[byteIndex] << 24) |
                                              (registerData[byteIndex + 1] << 16) |
                                              (registerData[byteIndex + 2] << 8) |
                                               registerData[byteIndex + 3];
                                float floatValue = BitConverter.ToSingle(BitConverter.GetBytes(intValue), 0);
                                registers[i] = (T)(object)floatValue;
                                i++; // 跳过下一个寄存器
                            }
                        }
                        else
                        {
                            return Result<T>.Failed($"不支持的类型: {typeof(T).FullName}");
                        }
                    }
                }

                return Result<T>.Success(registers.ToList());
            }
            catch (Exception ex)
            {
                return Result<T>.Failed($"读取寄存器失败: {ex.Message}");
            }
        }

        // 3. 写（线圈状态 、输入线圈），使用5、15功能码
        /// <summary>
        /// 写单个或多个线圈
        /// </summary>
        /// <param name="slaveNum">从站地址</param>
        /// <param name="startAddr">起始地址</param>
        /// <param name="datas">线圈值列表</param>
        /// <returns>操作结果</returns>
        public virtual Result<bool> WriteCoils(byte slaveNum, ushort startAddr, List<bool> datas)
        {
            try
            {
                bool isSingleWrite = datas.Count == 1;
                byte funcCode = isSingleWrite ? (byte)0x05 : (byte)0x0F;

                if (isSingleWrite)
                {
                    // 写单个线圈
                    ushort value = datas[0] ? (ushort)0xFF00 : (ushort)0x0000;
                    var pdu = BuildProtocolDataUnit(slaveNum, funcCode, startAddr, value);
                    var response = SendRequest(pdu);

                    // 验证响应
                    if (response.Length < 4 || response[0] != slaveNum || response[1] != funcCode ||
                        BitConverter.ToUInt16(new byte[] { response[3], response[2] }, 0) != startAddr ||
                        BitConverter.ToUInt16(new byte[] { response[5], response[4] }, 0) != value)
                    {
                        return Result<bool>.Failed("无效的响应格式");
                    }

                    return Result<bool>.Success();
                }
                else
                {
                    // 写多个线圈
                    int coilCount = datas.Count;
                    int byteCount = (coilCount + 7) / 8;
                    byte[] values = new byte[byteCount];

                    for (int i = 0; i < coilCount; i++)
                    {
                        int byteIndex = i / 8;
                        int bitIndex = i % 8;
                        if (datas[i])
                        {
                            values[byteIndex] |= (byte)(1 << bitIndex);
                        }
                    }

                    var pdu = BuildProtocolDataUnit(slaveNum, funcCode, startAddr, (ushort)coilCount, values);
                    var response = SendRequest(pdu);

                    // 验证响应
                    if (response.Length < 6 || response[0] != slaveNum || response[1] != funcCode ||
                        BitConverter.ToUInt16(new byte[] { response[3], response[2] }, 0) != startAddr ||
                        BitConverter.ToUInt16(new byte[] { response[5], response[4] }, 0) != coilCount)
                    {
                        return Result<bool>.Failed("无效的响应格式");
                    }

                    return Result<bool>.Success();
                }
            }
            catch (Exception ex)
            {
                return Result<bool>.Failed($"写线圈失败: {ex.Message}");
            }
        }

        // 4. 写（保持型寄存器、输入寄存器），使用6、16功能码
        /// <summary>
        /// 写单个或多个寄存器
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="slaveNum">从站地址</param>
        /// <param name="startAddr">起始地址</param>
        /// <param name="datas">寄存器值列表</param>
        /// <returns>操作结果</returns>
        public virtual Result<bool> WriteRegisters<T>(byte slaveNum, ushort startAddr, List<T> datas)
        {
            try
            {
                bool isSingleWrite = datas.Count == 1;
                byte funcCode = isSingleWrite ? (byte)0x06 : (byte)0x10;

                if (isSingleWrite)
                {
                    // 写单个寄存器
                    T value = datas[0];
                    ushort ushortValue = 0;

                    if (value is ushort)
                    {
                        ushortValue = (ushort)(object)value;
                    }
                    else if (value is short)
                    {
                        ushortValue = (ushort)(short)(object)value;
                    }
                    else if (value is int)
                    {
                        // 只取低16位
                        ushortValue = (ushort)((int)(object)value & 0xFFFF);
                    }
                    else
                    {
                        return Result<bool>.Failed($"不支持的类型: {typeof(T).FullName}");
                    }

                    var pdu = BuildProtocolDataUnit(slaveNum, funcCode, startAddr, ushortValue);
                    var response = SendRequest(pdu);

                    // 验证响应
                    if (response.Length < 4 || response[0] != slaveNum || response[1] != funcCode ||
                        BitConverter.ToUInt16(new byte[] { response[3], response[2] }, 0) != startAddr ||
                        BitConverter.ToUInt16(new byte[] { response[5], response[4] }, 0) != ushortValue)
                    {
                        return Result<bool>.Failed("无效的响应格式");
                    }

                    return Result<bool>.Success();
                }
                else
                {
                    // 写多个寄存器
                    int registerCount = datas.Count;
                    int byteCount = registerCount * 2;
                    byte[] values = new byte[byteCount];

                    for (int i = 0; i < registerCount; i++)
                    {
                        T value = datas[i];
                        int byteIndex = i * 2;

                        if (value is ushort)
                        {
                            ushort ushortValue = (ushort)(object)value;
                            values[byteIndex] = (byte)(ushortValue >> 8);
                            values[byteIndex + 1] = (byte)(ushortValue & 0xFF);
                        }
                        else if (value is short)
                        {
                            short shortValue = (short)(object)value;
                            values[byteIndex] = (byte)(shortValue >> 8);
                            values[byteIndex + 1] = (byte)(shortValue & 0xFF);
                        }
                        else if (value is int)
                        {
                            int intValue = (int)(object)value;
                            // 写入低16位
                            values[byteIndex] = (byte)((intValue >> 8) & 0xFF);
                            values[byteIndex + 1] = (byte)(intValue & 0xFF);
                        }
                        else if (value is float)
                        {
                            float floatValue = (float)(object)value;
                            int intValue = BitConverter.SingleToInt32Bits(floatValue);
                            // 写入低16位
                            values[byteIndex] = (byte)((intValue >> 8) & 0xFF);
                            values[byteIndex + 1] = (byte)(intValue & 0xFF);
                        }
                        else
                        {
                            return Result<bool>.Failed($"不支持的类型: {typeof(T).FullName}");
                        }
                    }

                    var pdu = BuildProtocolDataUnit(slaveNum, funcCode, startAddr, (ushort)registerCount, values);
                    var response = SendRequest(pdu);

                    // 验证响应
                    if (response.Length < 6 || response[0] != slaveNum || response[1] != funcCode ||
                        BitConverter.ToUInt16(new byte[] { response[3], response[2] }, 0) != startAddr ||
                        BitConverter.ToUInt16(new byte[] { response[5], response[4] }, 0) != registerCount)
                    {
                        return Result<bool>.Failed("无效的响应格式");
                    }

                    return Result<bool>.Success();
                }
            }
            catch (Exception ex)
            {
                return Result<bool>.Failed($"写寄存器失败: {ex.Message}");
            }
        }



        #endregion

         
        /// <summary>
        /// 子类或衍生类实际实现中需要根据通信方式实现
        /// </summary>
        /// <param name="pdu"></param>
        /// <returns></returns>
        public virtual byte[] SendRequest(List<byte> pdu)
        {
            // 这里应该有实际的通信代码，必须在子类实现，返回响应字节 
            //Code...
            return pdu.ToArray(); 
        }

        #region Dispose 资源释放

        //调用Dispose(false)：这是实现IDisposable模式的标准做法。Dispose(bool disposing)是一个受保护的虚方法，通常有两种调用场景：
        //Dispose(true)：由用户显式调用Dispose()时触发，同时释放托管资源和非托管资源。
        //Dispose(false)：由析构函数调用，仅释放非托管资源（因为此时托管资源可能已被垃圾回收）。

        /// <summary>
        /// 实现IDisposable接口，确保资源正确释放
        /// </summary>
        private bool disposed = false;

        /// <summary>
        /// Dispose(true)：由用户显式调用Dispose()时触发，同时释放托管资源和非托管资源。
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);//终结器，确保资源释放
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    // 释放托管资源
                    CommunicationUnit?.Close();
                    CommunicationUnit = null;
                }

                // 释放非托管资源（如果有）

                disposed = true;
            }
        }

        /// <summary>
        /// 析构函数
        /// Dispose(false)：由析构函数调用，仅释放非托管资源（因为此时托管资源可能已被垃圾回收）。
        /// </summary>
        ~ModbusBase()
        {
            Dispose(false);
        }

        #endregion
    }
}